package com.hfxt.controller;

import com.alibaba.fastjson.JSONObject;
import com.hfxt.config.WxConfig;
import com.hfxt.constants.Constants;
import com.hfxt.dto.Result;
import com.hfxt.dto.UsersDto;
import com.hfxt.po.Users;
import com.hfxt.service.UsersService;
import com.hfxt.utils.RedisUtils;
import com.hfxt.utils.ResultUtils;
import com.hfxt.utils.StringUtil;
import com.hfxt.utils.UrlUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

@RequestMapping("/api/user")
@RestController
public class UsersController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UsersService usersService;

    @Autowired
    private WxConfig wxConfig;

    @RequestMapping("/login/sms")
    public Result loginBySms(String phone, String sms) throws Exception {
        //判断手机号和验证码是否为空
        //判断手机号和验证码是否正确
        String key = StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX, Constants.RedisKey.SMS_PRIFIX, phone, Constants.Sms.CodeType.LOGIN_OR_REGISTER + "");
        String redisCode = redisUtils.getValue(key);
        //如果验证码在redis中已经不存在或不相等，则提示验证码错误
       /* if(StringUtil.isBlank(redisCode) || !sms.equals(redisCode)){
            throw new BaseException(ResultEnum.FAIL_VERIFY);
       }*/
        //验证码使用后，别人就不能再用，所以，可以删除了
        //redisUtils.delete(key);
        //判断用户是否存在
        // 如果用户不存在，则添加用户
        Users users = usersService.queryUsersByPhone(phone);
        if (null == users) {
            users = new Users();
            users.setAccount(phone);
            users.setUserName(phone);
            users.setIsAuthentication(0);//是否冻结
            users.setIsDelete(0);//是否被删除，0表示没有被删除
            usersService.qdtxAddUsers(users);
        }

        //如果用户存在，则生成token
        String token = StringUtil.createToken();
        //构造存储在redis中的key,对应的值存储用户信息UsersDto(区别于实体类Users)
        String tokenKey = StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX, Constants.RedisKey.TOKEN_PRIFIX, token);
        UsersDto usersDto = new UsersDto();
        BeanUtils.copyProperties(users, usersDto);
        redisUtils.set(tokenKey, JSONObject.toJSONString(usersDto), Constants.Duration.HALF_HOUR_INT);
        //将token返回给前端
        return ResultUtils.returnDataSuccess(StringUtil.createSimpleMap("token", token));
    }

    @RequestMapping("/info")
    public Result info(HttpServletRequest request) throws Exception {
        String token = request.getHeader("token");
        String tokenKey = StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX, Constants.RedisKey.TOKEN_PRIFIX, token);
        String userDtoJson = redisUtils.getValue(tokenKey);
        /*if(StringUtil.isBlank(userDtoJson)){
            throw new BaseException(ResultEnum.FILE_NOT_LOGIN);
        }*/
        UsersDto usersDto = JSONObject.parseObject(userDtoJson, UsersDto.class);
        //return ResultUtils.returnDataSuccess(userDtoJson);
        return new Result("0", "成功", usersDto);
    }

    @RequestMapping("/login/wechat")  //跳到二维码授权登录页面
    public void wechat(HttpServletResponse response) throws Exception {
        response.sendRedirect(wxConfig.getCodeUrl() + "?appid=" + wxConfig.getAppId() + "&redirect_uri=" + wxConfig.getRedirectUri() + "&response_type=" + wxConfig.getResponseType() + "&scope=" + wxConfig.getScope() + "&state=" + wxConfig.getState() + "#wechat_redirect");
    }

    @RequestMapping(value = "/wechat/callback", produces = {"application/json;charset=UTF-8"})
    public Result callBack(String code, HttpServletResponse response) throws Exception {
        //根据code获取accessToken
        StringBuffer accessTokenSb = new StringBuffer(wxConfig.getAccessTokenUrl());
        accessTokenSb.append("?appid=" + wxConfig.getAppId());
        accessTokenSb.append("&secret=" + wxConfig.getSecret());
        accessTokenSb.append("&code=" + code);
        accessTokenSb.append("&grant_type=" + wxConfig.getGrantType());
        String accessTokenJson = UrlUtils.loadURL(accessTokenSb.toString());
        JSONObject jsonObject = JSONObject.parseObject(accessTokenJson);
        System.out.println(accessTokenJson);
        String accessToken = (String) jsonObject.get("access_token");
        String openId = (String) jsonObject.get("openid");

        StringBuffer userInfoSb = new StringBuffer(wxConfig.getUserInfoUrl());
        userInfoSb.append("?access_token=" + accessToken);
        userInfoSb.append("&openId=" + openId);

        String userJson = UrlUtils.loadURL(userInfoSb.toString());

        JSONObject userJsonObject = JSONObject.parseObject(userJson);

        Users users = null;
        users = usersService.queryUsersByOpenId(openId);
        if (null == users) {
            users = new Users();
            users.setOpenId(openId);
            users.setUserName(userJsonObject.getString("nickname"));
            users.setFaceUrl(userJsonObject.getString("headimgurl"));
            users.setIsAuthentication(0);
            users.setIsDelete(0);
            users.setAccount(userJsonObject.getString("nickname"));
            usersService.qdtxAddUsers(users);
        }
        String token = createToken(users);
        response.sendRedirect(wxConfig.getRedirectUrl() + "?token=" + token + "&name=" + URLEncoder.encode(users.getUserName()));
        return ResultUtils.returnSuccess();
    }

    public String createToken(Users users) throws Exception {
        String token = StringUtil.createToken();
        //保存token
        String tokenKey = StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX, Constants.RedisKey.TOKEN_PRIFIX, token);
        UsersDto usersDto = new UsersDto();
        BeanUtils.copyProperties(users, usersDto);
        redisUtils.set(tokenKey, JSONObject.toJSONString(usersDto), Constants.Duration.HALF_HOUR_INT);
        return token;
    }
}
